package com.wlit.print;

import com.alibaba.fastjson.JSONObject;
import com.caysn.autoreplyprint.AutoReplyPrint;
import com.caysn.autoreplyprint.AutoReplyPrint.CP_OnPortClosedEvent_Callback;
import com.caysn.autoreplyprint.AutoReplyPrint.CP_OnPrinterPrintedEvent_Callback;
import com.caysn.autoreplyprint.AutoReplyPrint.CP_OnPrinterReceivedEvent_Callback;
import com.caysn.autoreplyprint.AutoReplyPrint.CP_OnPrinterStatusEvent_Callback;
import com.caysn.autoreplyprint.AutoReplyPrint.CP_PrinterStatus;
import com.caysn.autoreplyprint.AutoReplyPrint.CP_Printer_GetPrinterFirmwareVersion_Helper;
import com.sun.jna.Pointer;
import com.sun.jna.WString;
import com.sun.jna.ptr.IntByReference;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class LabelPrinter {
    private static LabelPrinter instance = null;

    private LabelPrinter() {
    }

    public static LabelPrinter getInstance() {
        if (instance == null) {
            instance = new LabelPrinter();
        }
        return instance;
    }

    private CP_OnPortClosedEvent_Callback closed_callback = new CP_OnPortClosedEvent_Callback() {
        public void CP_OnPortClosedEvent(Pointer handle, Pointer private_data) {
            System.out.println("Port Closed");
        }
    };
    private CP_OnPrinterStatusEvent_Callback status_callback = new CP_OnPrinterStatusEvent_Callback() {
        public void CP_OnPrinterStatusEvent(Pointer h, long printer_error_status, long printer_info_status, Pointer private_data) {
            Calendar calendar = Calendar.getInstance();
            Date calendarDate = calendar.getTime();
            String time = (new SimpleDateFormat("yyyy-MM-dd kk:mm:ss")).format(calendarDate);
            CP_PrinterStatus status = new CP_PrinterStatus(printer_error_status, printer_info_status);
            String error_status_string = String.format(" Printer Error Status: 0x%04X", printer_error_status & 65535L);
            if (status.ERROR_OCCURED()) {
                if (status.ERROR_CUTTER()) {
                    error_status_string = error_status_string + "[ERROR_CUTTER]";
                }

                if (status.ERROR_FLASH()) {
                    error_status_string = error_status_string + "[ERROR_FLASH]";
                }

                if (status.ERROR_NOPAPER()) {
                    error_status_string = error_status_string + "[ERROR_NOPAPER]";
                }

                if (status.ERROR_VOLTAGE()) {
                    error_status_string = error_status_string + "[ERROR_VOLTAGE]";
                }

                if (status.ERROR_MARKER()) {
                    error_status_string = error_status_string + "[ERROR_MARKER]";
                }

                if (status.ERROR_ENGINE()) {
                    error_status_string = error_status_string + "[ERROR_ENGINE]";
                }

                if (status.ERROR_OVERHEAT()) {
                    error_status_string = error_status_string + "[ERROR_OVERHEAT]";
                }

                if (status.ERROR_COVERUP()) {
                    error_status_string = error_status_string + "[ERROR_COVERUP]";
                }

                if (status.ERROR_MOTOR()) {
                    error_status_string = error_status_string + "[ERROR_MOTOR]";
                }
            }

            String info_status_string = String.format(" Printer Info Status: 0x%04X", printer_info_status & 65535L);
            if (status.INFO_LABELMODE()) {
                info_status_string = info_status_string + "[Label Mode]";
            }

            if (status.INFO_LABELPAPER()) {
                info_status_string = info_status_string + "[Label Paper]";
            }

            if (status.INFO_PAPERNOFETCH()) {
                info_status_string = info_status_string + "[Paper Not Fetch]";
            }

            System.out.println(time + error_status_string);
            System.out.println(time + info_status_string);
        }
    };
    private CP_OnPrinterReceivedEvent_Callback received_callback = new CP_OnPrinterReceivedEvent_Callback() {
        public void CP_OnPrinterReceivedEvent(Pointer h, int printer_received_byte_count, Pointer private_data) {
            Calendar calendar = Calendar.getInstance();
            Date calendarDate = calendar.getTime();
            String time = (new SimpleDateFormat("yyyy-MM-dd kk:mm:ss")).format(calendarDate);
            System.out.println(time + " PrinterReceived: " + printer_received_byte_count);
        }
    };
    private CP_OnPrinterPrintedEvent_Callback printed_callback = new CP_OnPrinterPrintedEvent_Callback() {
        public void CP_OnPrinterPrintedEvent(Pointer h, int printer_printed_page_id, Pointer private_data) {
            Calendar calendar = Calendar.getInstance();
            Date calendarDate = calendar.getTime();
            String time = (new SimpleDateFormat("yyyy-MM-dd kk:mm:ss")).format(calendarDate);
            System.out.println(time + " PrinterPrinted: " + printer_printed_page_id);
        }
    };

    private Pointer h = Pointer.NULL;



    public void AddCallback() {
        AutoReplyPrint.INSTANCE.CP_Port_AddOnPortClosedEvent(this.closed_callback, Pointer.NULL);
        AutoReplyPrint.INSTANCE.CP_Printer_AddOnPrinterStatusEvent(this.status_callback, Pointer.NULL);
        AutoReplyPrint.INSTANCE.CP_Printer_AddOnPrinterReceivedEvent(this.received_callback, Pointer.NULL);
        AutoReplyPrint.INSTANCE.CP_Printer_AddOnPrinterPrintedEvent(this.printed_callback, Pointer.NULL);
    }

    public void RemoveCallback() {
        AutoReplyPrint.INSTANCE.CP_Port_RemoveOnPortClosedEvent(this.closed_callback);
        AutoReplyPrint.INSTANCE.CP_Printer_RemoveOnPrinterStatusEvent(this.status_callback);
        AutoReplyPrint.INSTANCE.CP_Printer_RemoveOnPrinterReceivedEvent(this.received_callback);
        AutoReplyPrint.INSTANCE.CP_Printer_RemoveOnPrinterPrintedEvent(this.printed_callback);
    }


    public void open(String name) {
        this.h = AutoReplyPrint.INSTANCE.CP_Port_OpenCom(name, 115200, 8, 0, 0, 0, 0);
        System.out.println("open:" + this.h);
    }

    public void close() {
        if (this.h != Pointer.NULL) {
            AutoReplyPrint.INSTANCE.CP_Port_Close(this.h);
            this.h = Pointer.NULL;
        }
    }

    public boolean isOpen() {
        return this.h != Pointer.NULL;
    }

    public void print(JSONObject jsonObject) {
        //String bianhao,String name, String room, String pure,String owner
        String bianhao = jsonObject.getString("bianhao");
        String name = jsonObject.getString("name");
        String room = jsonObject.getString("room");
        String pure = jsonObject.getString("pure");
        String owner = jsonObject.getString("owner");

        //AutoReplyPrint.INSTANCE.CP_Label_EnableLabelMode(this.h);
        AutoReplyPrint.INSTANCE.CP_Pos_SetMultiByteMode(this.h);
        AutoReplyPrint.INSTANCE.CP_Pos_SetMultiByteEncoding(this.h, 1);
        AutoReplyPrint.INSTANCE.CP_Label_PageBegin(this.h, 0, 0, 384, 284, 0);
        AutoReplyPrint.INSTANCE.CP_Label_DrawTextInUTF8(this.h, 5, 20, 24, 0, new WString("编号:"+bianhao));
        AutoReplyPrint.INSTANCE.CP_Label_DrawTextInUTF8(this.h, 5, 50, 24, 0, new WString("品名:"+name));
        AutoReplyPrint.INSTANCE.CP_Label_DrawTextInUTF8(this.h, 5, 80, 24, 0, new WString("存放地:"+room));
        AutoReplyPrint.INSTANCE.CP_Label_DrawTextInUTF8(this.h, 5, 110, 24, 0, new WString("纯度:"+pure));
        AutoReplyPrint.INSTANCE.CP_Label_DrawTextInUTF8(this.h, 5, 140, 24, 0, new WString("专属人:"+owner));
        AutoReplyPrint.INSTANCE.CP_Label_DrawQRCode(this.h, 200, 110, 0, 1, 8, 0, bianhao);
        AutoReplyPrint.INSTANCE.CP_Label_PagePrint(this.h, 1);
        AutoReplyPrint.INSTANCE.CP_Pos_HalfCutPaper(this.h);
        boolean result = AutoReplyPrint.INSTANCE.CP_Pos_QueryPrintResult(this.h, 30000);
        System.out.println("result:" + result);
    }

    public void showInfo() {
        boolean isOPen = AutoReplyPrint.INSTANCE.CP_Port_IsOpened(this.h);
        System.out.println("isOPen:" + isOPen);
        String firmware = CP_Printer_GetPrinterFirmwareVersion_Helper.GetPrinterFirmwareVersion(this.h);
        System.out.println("firmware:" + firmware);
        IntByReference width_mm = new IntByReference();
        IntByReference height_mm = new IntByReference();
        IntByReference dots_per_mm = new IntByReference();
        AutoReplyPrint.INSTANCE.CP_Printer_GetPrinterResolutionInfo(this.h, width_mm, height_mm, dots_per_mm);
        System.out.println("width_mm:" + width_mm.getValue() + ", height_mm:" + height_mm.getValue() + ", dots_per_mm:" + dots_per_mm.getValue());
    }
}
